package tech.yixiyun.framework.kuafu.controller.annotation;


import tech.yixiyun.framework.kuafu.component.Component;

import java.lang.annotation.*;

/**
 * 该注解用于将类标记为Controller类，框架启动时会扫描Controller类，找到类里所有非private修饰的
 * 并且返回值类型是View的方法，生成路由映射关系。一个方法对应一个请求路径。<br/><br/>
 * 请求路径生成规则 一般就是 基础路径 + / + 方法名 。比如现在有一个使用了@Controller注解的UserController的类，它里面有一个返回值类型是View的方法 add(),
 * 这个UserController类的基础路径是 user，那么按照默认规则，框架为这个add方法生成的映射路径就是 user/add了。
 * 如果你不想用默认规则生成的路径，你可以直接在方法上
 * 使用 @Route 注解来指定这个方法映射的路径。<br/><br/>
 * Controller类对应的基础路径就由该注解的value属性指定，value的属性值支持一些特定的语法，详情请查看value的注释说明<br/>
 * 另外该注解是可继承的，强烈推荐先写一个父类（也可以直接使用框架提供的BaseController），在父类上使用 @Controller 注解配置好规则，然后让其他Controller类
 * 都来继承这个父类，就不用在每个Controller类上重复配置 @Controller 了。<br/><br/>
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Component
public @interface Controller {

    /**
     * <b>指定Controller类映射的基础路径，默认就是该类的类名。</b><br/>
     * 例如现在有一个UserController类，使用了@Controller注解，默认情况下，这个类映射的基础路径就是
     *  UserController , 现在我们可以通过两种方式改变这个默认值<br/>
     *  <b>一种是通过一些特殊语法来基于这个默认值来进行改造</b>，例如：<br/>
     *  (a)让首字母小写，如果让 value = (a)，那么映射的基础路径就变成了 userController <br/>
     *  (aa) 让所有字母小写 ，value = (aa) : usercontroller<br/>
     *  (AA) 让所有字母大写 ，value = (AA) : USERCONTROLLER <br/>
     *  (!Controller) !去掉某个字符串 ，value = (a)(!Controller) : user <br/>
     *  (Controller~Base) ~替换某个字符串，~前面是原字符串，后面是替换值，<br/>
     *  value = (a)(Controller~_abc) : user_abc <br/>
     *  (admin/+/base) + 在源字符串的前后拼接字符串，+ 前面字符串就拼接到源字符串的前面，+ 后面的字符串就是拼接到源字符串的后面，
     *  可以只拼接前面或者只拼接后面。 <br/>
     *  value = (a)(!Controller)(admin/+/base)  : admin/user/base <br/>
     *  以上规格可以多个联合使用，但一定要注意前后顺序，框架是按照你写的顺序来对默认值做管道处理的。<b>并且不支持嵌套使用</b><br/>
     *  可以通过 PathResolver.resolve() 测试一下你写的规则对不对 <br/><br/>
     *  <b>另一种写法就是完全指定</b>，例如 value = abcdefg，那么映射的基础路径就是 abcdefg ，<br/>
     *  <b>注意：</b> 要不就完全指定，要不就通过语法规则指定，不能两种同时使用。一旦检测到有()，就会优先按照语法规则解析，抛弃完全指定的字符串
     *
     * @return
     */
    String value() default "";


}
